#include <QCoreApplication>
#include <QKeyEvent>
#include <QMessageBox>
#include <QScriptEngine>
#include <QScriptValueIterator>

#include "RtScriptConsole.h"

#include "RtSession.h"

#include "RtRoot.h"

RtScriptConsole::RtScriptConsole(void)
{

	setTabStopWidth ( 40 );

    session = new RtSession(this);

	connect(session,SIGNAL(stdOut(const QString&)),this,SLOT(stdOut(const QString&)));
	connect(session,SIGNAL(stdErr(const QString&)),this,SLOT(stdErr(const QString&)));
    connect(session,SIGNAL(endSession()),this,SLOT(endSession()));
}

void RtScriptConsole::exec(const QString& code)
{
	session->evaluate(code);
}
bool RtScriptConsole::canEvaluate(const QString& code)
{
	return session->canEvaluate(code);
}

void RtScriptConsole::closeEvent ( QCloseEvent * e )
{
	bool ok = true;

	if (session->isEvaluating())
	{
		QMessageBox::StandardButton ret;
        ret = QMessageBox::warning(this, windowTitle(),
                     tr("A script is currently executing.\n"
					    "Closing this console will terminate execution.\n"
                        "Do you want to close the console?"),
						QMessageBox::Close | QMessageBox::Cancel );
		ok = ret==QMessageBox::Close;
		if (ok) 
		{
			session->abortEvaluation();
			QCoreApplication::postEvent(parentWidget(),new QCloseEvent());
		}
		e->ignore();
	}
	else
	{
        //QWidget* p = parentWidget();
        //if (p) p->close();
        //parentWidget()->close();
		e->accept();	
	}

	/*if (ok)
	{
		QWidget* w = parentWidget();
		w->close();
		e->accept();
	}
	else e->ignore();*/
}

void RtScriptConsole::keyPressEvent (QKeyEvent * e)
{
	if (e->modifiers() & Qt::ControlModifier)
	{
		int k = e->key();
		if (k==Qt::Key_Cancel || k==Qt::Key_Pause)
		{
			session->abortEvaluation();
			e->accept();
			return;
		}
	}
	
	QConsoleWidget::keyPressEvent(e);
}

QStringList RtScriptConsole::introspection(const QString& lookup)
{
    if (lookup.isEmpty()) return QStringList();

	QStringList found;

	RtObject* obj = RtObject::findByName(lookup);
	if (obj)
	{
		foreach(RtObject* o, obj->children()) found << o->objectName();
		return found;
	}

    QScriptEngine* eng = session->getEngine();
    QScriptValue scriptObj = eng->globalObject();
    QStringList tokens = lookup.split('.');


    bool objFound;
    do
    {
        objFound = false;

        QString str = tokens.front();
        tokens.pop_front();

        QScriptValueIterator it(scriptObj);
        while (it.hasNext())
        {
            it.next();
            QString valueName = it.name();
            if (valueName==str)
            {
                scriptObj = it.value();
                objFound = true;
                break;
            }
        }
     }
    while (objFound && !tokens.isEmpty());

    if (objFound)
    {
        QScriptValueIterator it(scriptObj);
        while (it.hasNext()) {
             it.next();
             found << it.name();
         }
    }

    return found;

}

